module Schnell
  # This module contains the factory methods that are used to access most html objects
  #
  # For example, to access a button on a web page that has the following html
  #  <input type = button name= 'b1' value='Click Me' onClick='javascript:doSomething()'>
  #
  # the following schnell code could be used
  #
  #  browser.button(:name, 'b1').click
  #
  # or
  #
  #  browser.button(:value, 'Click Me').id
  #
  # there are many methods available to the Button object
  #
  module Container
    # This is the main method for accessing a button. Often declared as an <input type = submit> tag.
    #  *  how   - symbol - how we access the button, :index, :id, :name etc
    #  *  what  - string, integer - what we are looking for,
    #
    # Valid values for 'how' are listed in the schnell Wiki - http://code.google.com/p/schnell-jruby/wiki/UserGuide
    #
    # Returns a Button object.
    #
    # Typical usage
    #
    #    browser.button(:id,    'b_1')                             # access the button with an ID of b_1
    #    browser.button(:name,  'verify_data')                     # access the button with a name of verify_data
    #    browser.button(:value, 'Login')                           # access the button with a value (the text displayed on the button) of Login
    #    browser.button(:index, 2)                                 # access the second button on the page (1 based, so the first button is accessed with :index,1)
    #
    def button(how,what)
      Button.new(driver, how, what)
    end
    
    # This is the main method for accessing a text field. Usually an <input type = text> HTML tag. or a text area - a  <textarea> tag
    #  *  how   - symbol - how we access the field, :index, :id, :name etc
    #  *  what  - string, integer - what we are looking for,
    #
    # Valid values for 'how' are listed in the schnell Wiki - http://code.google.com/p/schnell-jruby/wiki/UserGuide
    #
    # returns a TextField object
    #
    # Typical Usage
    #
    #    browser.text_field(:id,   'user_name')                 # access the text field with an ID of user_name
    #    browser.text_field(:name, 'address')                   # access the text field with a name of address
    #    browser.text_field(:index, 2)                          # access the second text field on the page (1 based, so the first field is accessed with :index,1)
    #
    def text_field(how,what)
      TextField.new(driver, how, what)
    end
    
    # This is the main method for accessing a check box. Usually an <input type = "checkbox"> HTML tag.
    #
    #  *  how   - symbol - how we access the check box - :index, :id, :name etc
    #  *  what  - string, integer - what we are looking for,
    #  *  value - string - when there are multiple objects with different value attributes, this can be used to find the correct object
    #
    # Valid values for 'how' are listed in the schnell Wiki -  http://code.google.com/p/schnell-jruby/wiki/UserGuide
    # returns a CheckBox object
    #
    # Typical usage
    #
    #    browser.checkbox(:id, 'send_email')                    # access the check box with an id of send_mail
    #    browser.checkbox(:name, 'send_copy')                   # access the check box with a name of send_copy
    #    browser.checkbox(:index, 2)                            # access the second check box on the page (1 based, so the first field is accessed with :index,1)
    #
    # In many instances, checkboxes on an html page have the same name, but are identified by different values. An example is shown next.
    #
    #  <input type = "checkbox" name = email_frequency value = 'daily' > Daily Email
    #  <input type = "checkbox" name = email_frequency value = 'Weekly'> Weekly Email
    #  <input type = "checkbox" name = email_frequency value = 'monthly'>Monthly Email
    #
    # schnell can access these using the following:
    #
    #    browser.checkbox(:id, 'day_to_send', 'monday')         # access the check box with an id of day_to_send and a value of monday
    #    browser.checkbox(:name,'email_frequency', 'weekly')    # access the check box with a name of email_frequency and a value of 'weekly'
    #
    def checkbox(how,what,value = nil)
      CheckBox.new(driver,how,what,value)
    end
    
    # This is the main method for accessing a radio button. Usually an <input type = "radio"> HTML tag.
    #
    #  *  how   - symbol - how we access the radio button - :index, :id, :name etc
    #  *  what  - string, integer - what we are looking for,
    #  *  value - string - when there are multiple objects with different value attributes, this can be used to find the correct object
    #
    # Valid values for 'how' are listed in the schnell Wiki -  http://code.google.com/p/schnell-jruby/wiki/UserGuide
    # returns a radio button object
    #
    # Typical usage
    #
    #    browser.radio(:id, 'send_email')                    # access the radio button with an id of send_mail
    #    browser.radio(:name, 'send_copy')                   # access the radio button with a name of send_copy
    #    browser.radio(:index, 2)                            # access the second radio button on the page (1 based, so the first field is accessed with :index,1)
    #
    # In many instances, radio buttons on an html page have the same name, but are identified by different values. An example is shown next.
    #
    #  <input type = "radio" name = email_frequency value = 'daily' > Daily Email
    #  <input type = "radio" name = email_frequency value = 'Weekly'> Weekly Email
    #  <input type = "radio" name = email_frequency value = 'monthly'>Monthly Email
    #
    # schnell can access these using the following:
    #
    #    browser.radio(:id, 'day_to_send', 'monday')         # access the radio button with an id of day_to_send and a value of monday
    #    browser.radio(:name,'email_frequency', 'weekly')    # access the radio button with a name of email_frequency and a value of 'weekly'
    #
    def radio(how,what,value = nil)
      Radio.new(driver, how, what,value)
    end
    
    # This is the main method for accessing a link.
    #  *  how   - symbol - how we access the link, :index, :id, :name, :title, :text, :url
    #  *  what  - string, integer - what we are looking for,
    #
    # Valid values for 'how' are listed in the schnell Wiki - http://code.google.com/p/schnell-jruby/wiki/UserGuide
    #
    # returns a Link object
    #
    # Typical Usage
    #
    #   browser.link(:url, "/login.html")              # access the first link whose url matches login. 
    #                                       # but the complete path must be used, ie.link(:url, 'http://myserver.com/my_path/login.asp')
    #   browser.link(:index,2)                   # access the second link on the page
    #   browser.link(:title, "Picture")         # access a link using the tool tip
    #   browser.link(:text, 'Click Me')          # access the link that has Click Me as its text
    def link(how,what)
      Link.new(driver,how,what)
    end
    
    # This is the main method for accessing a selection list. Usually a <select> HTML tag.
    #  *  how   - symbol - how we access the selection list, :index, :id, :name etc
    #  *  what  - string, integer - what we are looking for,
    #
    # Valid values for 'how' are listed in the schnell Wiki - http://code.google.com/p/schnell-jruby/wiki/UserGuide
    #
    # returns a SelectList object
    #
    # Typical usage
    #
    #    browser.select_list(:id, 'currency')                   # access the select box with an id of currency
    #    browser.select_list(:name, 'country')                  # access the select box with a name of country
    #    browser.select_list(:index, 2)                         # access the second select box on the page (1 based, so the first field is accessed with :index,1)
    def select_list(how,what)
      SelectList.new(driver,how,what)
    end
    
    # This is the main method for accessing images - normally an <img src="image.gif"> HTML tag.
    #  *  how   - symbol - how we access the image, :index, :id, :name, :src, :title or :alt are supported
    #  *  what  - string, integer - what we are looking for,
    #
    # Valid values for 'how' are listed in the Schnell Wiki - http://code.google.com/p/schnell-jruby/wiki/UserGuide
    #
    # returns an Image object
    #
    # Typical Usage
    #
    #   browser.image(:src, "images/triangle.jpg")             # access the first image that matches source "images/triangle.jpg"
    #   browser.image(:index,2)                  # access the second image on the page
    #   browser.image(:alt, "A Picture")         # access an image using the alt text
    #    
    def image(how,what)
      Image.new(driver, how, what)
    end

    # Todo - Work on the frame to be done in next release    
    def frame(how,what)
      frame = Frame.new(driver, how, what)  
      driver = frame.assert_exists
      return frame
    end
    
    # This is the main method for accessing li tags
    #  *  how   - symbol - how we access the li, 
    #  *  what  - string, integer - what we are looking for,
    #
    # Valid values for 'how' are listed in the Schnell Wiki - http://code.google.com/p/schnell-jruby/wiki/UserGuide
    #
    # returns a li object
    #
    # Typical Usage
    #
    #   browser.li(:id, "list")                 # access the first li that matches list.
    #   browser.li(:index,2)                    # access the second li on the page
    #   browser.li(:title, "A Picture")        # access a li using the tooltip text
    #       
    def li(how,what)
      Li.new(driver, how, what)
    end
    
    # This is the main method for accessing map tags
    #  *  how   - symbol - how we access the map,
    #  *  what  - string, integer - what we are looking for,
    #
    # Valid values for 'how' are listed in the Schnell Wiki - http://code.google.com/p/schnell-jruby/wiki/UserGuide
    #
    # returns a map object
    #
    # Typical Usage
    #
    #   browser.map(:id, "list")                 # access the first map that matches list.
    #   browser.map(:index,2)                    # access the second map on the page
    #   browser.map(:title, "A Picture")         # access a map using the tooltip text.
    #    
    
    def map(how,what)
      Map.new(driver, how, what)
    end

    # This is the main method for accessing area tags
    #  *  how   - symbol - how we access the area
    #  *  what  - string, integer - what we are looking for,
    #
    # Valid values for 'how' are listed in the Schnell Wiki - http://code.google.com/p/schnell-jruby/wiki/UserGuide
    #
    # returns a area object
    #
    # Typical Usage
    #
    #   ie.area(:id, /list/)                 # access the first area that matches list.
    #   ie.area(:index,2)                    # access the second area on the page
    #   ie.area(:title, "A Picture")         # access a area using the tooltip text.
    #    
    
    def area(how,what)
      Area.new(driver, how, what)
    end
    
    # This is the main method for accessing span tags
    #  *  how   - symbol - how we access the span, 
    #  *  what  - string, integer - what we are looking for,
    #
    # Valid values for 'how' are listed in the Schnell Wiki - http://code.google.com/p/schnell-jruby/wiki/UserGuide
    #
    # returns a Span object
    #
    # Typical Usage
    #
    #   browser.span(:id, "list")                 # access the first span that matches list.
    #   browser.span(:index,2)                    # access the second span on the page
    #   browser.span(:title, "A Picture")         # access a span using the tooltip text.
    #    
    def span(how,what)
      Span.new(driver, how, what)
    end

    # This is the main method for accessing a text area. Usually a text area - a <textarea> tag
    #  *  how   - symbol - how we access the field, :index, :id, :name etc
    #  *  what  - string, integer - what we are looking for,
    #
    # Valid values for 'how' are listed in the Schnell Wiki - http://code.google.com/p/schnell-jruby/wiki/UserGuide
    #
    # returns a TextField object
    #
    # Typical Usage
    #
    #    browser.text_field(:id,   'user_name')                 # access the text field with an ID of user_name
    #    browser.text_field(:name, 'address')                   # access the text field with a name of address
    #    browser.text_field(:index, 2)                          # access the second text field on the page (1 based, so the first field is accessed with :index,1)
    
    def text_area(how,what)
      TextArea.new(driver, how, what)
    end
    
    # This is the main method for accessing a hidden field. Usually an <input type = hidden> HTML tag
    #
    #  *  how   - symbol - how we access the hidden field, :index, :id, :name etc
    #  *  what  - string, integer or regular expression - what we are looking for,
    #
    # Valid values for 'how' are listed in the Watir Wiki - http://code.google.com/p/schnell-jruby/wiki/UserGuide
    #
    # returns a Hidden object
    #
    # Typical usage
    #
    #    browser.hidden(:id, 'session_id')                 # access the hidden field with an ID of session_id
    #    browser.hidden(:name, 'temp_value')               # access the hidden field with a name of temp_value
    #    browser.hidden(:index, 2)                         # access the second hidden field on the page (1 based, so the first field is accessed with :index,1)
    #
    def hidden(how,what)
      Hidden.new(EnclosingElement.store, how, what)
    end    

    # This is the main method for accessing pre tags
    #  *  how   - symbol - how we access the pre, valid values are
    #    :index      - finds the item using its index
    #    :id         - finds the item using its id attribute
    #    :name       - finds the item using its name attribute
    #  *  what  - string, integer, what we are looking for,
    #
    # returns a Pre object
    #
    # Typical Usage
    #
    #   browser.pre(:id, "list")                 # access the first pre tag  that matches list.
    #   browser.pre(:index,2)                    # access the second pre tag on the page
    #   browser.pre(:title, "A Picture")         # access a pre tag using the tooltip text.
    #    
    def pre(how,what)
      Pre.new(driver, how, what)
    end
    
    # This is the main method for accessing divs. 
    #  *  how   - symbol - how we access the div
    #  *  what  - string, integer - what we are looking for,
    #
    # Valid values for 'how' are listed in the Watir Wiki - http://code.google.com/p/schnell-jruby/wiki/UserGuide
    #
    # returns an Div object
    #
    # Typical Usage
    #
    #   browser.div(:id, "list")                 # access the first div that matches list.
    #   browser.div(:index,2)                    # access the second div on the page
    #   browser.div(:title, "A Picture")         # access a div using the tooltip text.
    #    
    def div(how,what)
      Div.new(driver, how, what)
    end
    
    # This is the main method for accessing p tags
    #  *  how   - symbol - how we access the p, 
    #  *  what  - string, integer - what we are looking for,
    #
    # Valid values for 'how' are listed in the Schnell Wiki - http://code.google.com/p/schnell-jruby/wiki/UserGuide
    #
    # returns a P object
    #
    # Typical Usage
    #
    #   browser.p(:id, "list")                 # access the first p tag  that matches list.
    #   browser.p(:index,2)                    # access the second p tag on the page
    #   browser.p(:title, "A Picture")         # access a p tag using the tooltip text.
    #
    def p(how, what)
      P.new(driver, how, what)
    end    
    
    # This is the main method for accessing the links collection. Returns a Links object
    #
    # Typical usage:
    #
    #   browser.links.each { |l| puts l.to_s }            # iterate through all the links on the page
    #   browser.links[1].to_s                             # goto the first link on the page
    #   browser.links.length                              # show how many links are on the page.
    #
    
    def links
      Links.new(driver)
    end

    # This is the main method for accessing the images collection. Returns an Images object
    #
    # Typical usage:
    #
    #   browser.images.each { |i| puts i.to_s }            # iterate through all the images on the page
    #   browser.images[1].to_s                             # goto the first image on the page
    #   browser.images.length                              # show how many images are on the page.
    #
    
    def images
      Images.new(driver)
    end
    
    # this is the method for accessing the text_fields iterator. It returns a Text_Fields object
    #
    # Typical usage:
    #
    #   browser.text_fields.each { |t| puts t.to_s }            # iterate through all the text fields on the page
    #   browser.text_fields[1].to_s                             # goto the first text field on the page
    #   browser.text_fields.length                              # show how many text field are on the page.
    #    
    def text_fields
      TextFields.new(driver)
    end
    
    # this is the method for accessing the check boxes iterator. Returns a CheckBoxes object
    #
    # Typical usage:
    #
    #   browser.checkboxes.each { |c| puts c.to_s }             # iterate through all the check boxes on the page
    #   browser.checkboxes[1].to_s                              # goto the first check box on the page
    #   browser.checkboxes.length                               # show how many check boxes are on the page.
    #    
    def checkboxes
      CheckBoxes.new(driver)
    end

    # This is the method for accessing the radio buttons iterator. Returns a Radios object
    #
    # Typical usage:
    #
    #   browser.radios.each { |r| puts r.to_s }            # iterate through all the radio buttons on the page
    #   browser.radios[1].to_s                             # goto the first radio button on the page
    #   browser.radios.length                              # show how many radio buttons are on the page.
    #    
    def radios
      Radios.new(driver)
    end

    # this is the method for accessing the select lists iterator. Returns a SelectLists object
    #
    # Typical usage:
    #
    #   browser.select_lists.each { |s| puts s.to_s }            # iterate through all the select boxes on the page
    #   browser.select_lists[1].to_s                             # goto the first select boxes on the page
    #   browser.select_lists.length                              # show how many select boxes are on the page.
    #
    def select_lists
      SelectLists.new(driver)
    end

    # this is the main method for accessing the buttons iterator. It returns a Buttons object
    #
    # Typical usage:
    #
    #   browser.buttons.each { |b| puts b.to_s }                   # iterate through all the buttons on the page
    #   browser.buttons[1].to_s                                    # goto the first button on the page
    #   browser.buttons.length                                     # show how many buttons are on the page.
    #
    def buttons
      Buttons.new(driver)
    end

    # this is the main method for accessing the lis iterator.
    #
    # Returns a lis object
    #
    # Typical usage:
    #
    #   browser.lis.each { |s| puts s.to_s }            # iterate through all the lis on the page
    #   browser.lis[1].to_s                             # goto the first li on the page
    #   browser.lis.length                              # show how many lis are on the page.
    #    
    def lis
      Lis.new(driver)
    end

    # this is the main method for accessing the maps iterator.
    #
    # Returns a maps object
    #
    # Typical usage:
    #
    #   browser.maps.each { |s| puts s.to_s }            # iterate through all the maps on the page
    #   browser.maps[1].to_s                             # goto the first map on the page
    #   browser.maps.length                              # show how many maps are on the page.
    #    
    def maps
      Maps.new(driver)
    end

    # this is the main method for accessing the ps iterator.
    #
    # Returns a Pres object
    #
    # Typical usage:
    #
    #   browser.pres.each { |pre| puts pre.to_s }        # iterate through all the pre tags on the page
    #   browser.pres[1].to_s                             # goto the first pre tag on the page
    #   browser.pres.length                              # show how many pre tags are on the page.
    #    
    def pres
      Pres.new(driver)
    end
    
    # this is the main method for accessing the areas iterator.
    #
    # Returns a areas object
    #
    # Typical usage:
    #
    #   browser.areas.each { |s| puts s.to_s }            # iterate through all the areas on the page
    #   browser.areas[1].to_s                             # goto the first area on the page
    #   browser.areas.length                              # show how many areas are on the page.
    #    
    def areas
      Areas.new(driver)
    end

    # this is the main method for accessing the divs iterator. Returns a Divs collection
    #
    # Typical usage:
    #
    #   browser.divs.each { |d| puts d.to_s }            # iterate through all the divs on the page
    #   browser.divs[1].to_s                             # goto the first div on the page
    #   browser.divs.length                              # show how many divs are on the page.
    #    
    def divs
      Divs.new(driver)
    end
    
    # this is the main method for accessing the spans iterator.
    #
    # Returns a Spans object
    #
    # Typical usage:
    #
    #   browser.spans.each { |s| puts s.to_s }            # iterate through all the spans on the page
    #   browser.spans[1].to_s                             # goto the first span on the page
    #   browser.spans.length                              # show how many spans are on the page.
    #    
    def spans
      Spans.new(driver)
    end
    
    # this is the main method for accessing the ps iterator.
    #
    # Returns a Ps object
    #
    # Typical usage:
    #
    #   browser.ps.each { |p| puts p.to_s }            # iterate through all the p tags on the page
    #   browser.ps[1].to_s                             # goto the first p tag on the page
    #   browser.ps.length                              # show how many p tags are on the page.
    #
    def ps
      Ps.new(driver)
    end
    
        # this is the method for accessing the hiddens iterator. It returns a Hiddens object
    #
    # Typical usage:
    #
    #   browser.hiddens.each { |t| puts t.to_s }            # iterate through all the hidden fields on the page
    #   browser.hiddens[1].to_s                             # goto the first hidden field on the page
    #   browser.hiddens.length                              # show how many hidden fields are on the page.
    #
    def hiddens
      Hiddens.new(EnclosingElement.store)
    end
    
    def locate_input_element(how,what,types,value=nil)
    end
    def locate_tagged_element(tag,how,what)
    end
  end
end
